package org.budo.graph.view.util;

import java.io.BufferedReader;
import java.io.File;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.budo.graph.Constant;
import org.budo.graph.view.AbstractBudoGraphViewSupport;
import org.budo.support.lang.util.BufferedReaderUtil;
import org.budo.support.lang.util.FileUtil;
import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.servlet.util.ResponseUtil;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;

/**
 * @author limingwei
 */
public class GraphAuthorizeUtil {
    private static final Logger log = Slf4j.getLogger();

    public static final String SESSION_USER_KEY = "druid-user";

    private static final String AUTH_FAILED = "{\"result\":{\"error\":\"authentication_failed\",\"error_description\":\"授权验证失败\"},\"status\":1101}";

    public static boolean checkAuthorize_2(HttpServletRequest request, AbstractBudoGraphViewSupport budoGraphViewSupport) {
        String usernameParam = request.getParameter(AbstractBudoGraphViewSupport.PARAM_NAME_USERNAME);
        String passwordParam = request.getParameter(AbstractBudoGraphViewSupport.PARAM_NAME_PASSWORD);

        return checkAuthorize_3(budoGraphViewSupport, usernameParam, passwordParam);
    }

    /**
     * 认证通过返回true 
     */
    private static boolean checkAuthorize_3(AbstractBudoGraphViewSupport budoGraphViewSupport, String usernameParam, String passwordParam) {
        Map<String, String> userMap = budoGraphViewSupport.getUserMap();
        if (null == userMap || userMap.isEmpty()) {
            log.warn("#139 userMap is null or empty, userMap=" + userMap);
            // do not return now
        }

        for (Entry<String, String> entry : userMap.entrySet()) {
            if (StringUtil.equals(entry.getKey(), usernameParam) //
                    && StringUtil.equals(entry.getValue(), passwordParam)) {
                return true; // login sucess
            }
        }

        // 用户文件
        String userFile = budoGraphViewSupport.getUserFile();
        if (null == userFile) {
            log.error("#270 userFile is null, budoGraphViewSupport=" + budoGraphViewSupport);
            return false;
        }

        File file = new File(userFile);
        if (!file.exists()) {
            log.error("#277 userFile not exists, userFile=" + FileUtil.getCanonicalPath(file));
            return false;
        }

        BufferedReader bufferedReader = new BufferedReader(IoUtil.fileReader(file));
        String line;
        while ((line = BufferedReaderUtil.readLine(bufferedReader)) != null) {
            if (null != line && line.equals(usernameParam + ":" + passwordParam)) {
                IoUtil.closeQuietly(bufferedReader);
                return true; // login sucess
            }
        }

        log.error("#295 user auth fail, usernameParam=" + usernameParam + ", passwordParam=" + passwordParam + ", userFile=" + FileUtil.getCanonicalPath(file));
        IoUtil.closeQuietly(bufferedReader);
        return false;
    }

    /**
     * 认证通过返回true 
     */
    public static boolean checkAuthorize(AbstractBudoGraphViewSupport budoGraphViewSupport, HttpServletRequest request) {
        // 通过 session 认证
        HttpSession httpSession = request.getSession();
        Object userInSession = httpSession.getAttribute(SESSION_USER_KEY);
        if (null != userInSession) {
            return true;
        }

        // 每次接口请求都传入用户名密码认证
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            return false;
        }

        return checkAuthorize_3(budoGraphViewSupport, username, password);
    }

    public static void handleNoAuth(HttpServletRequest request, HttpServletResponse response) {
        log.warn("#99 handleNoAuth, request="+request); 

        if (StringUtil.isNotBlank(request.getHeader("X-Requested-With"))) { // 是 AJAX 请求
            IoUtil.write(AUTH_FAILED, ResponseUtil.getOutputStream(response));
            return;
        }

        String url = request.getContextPath() + Constant.URL_ROOT + "/login.html";
        ResponseUtil.sendRedirect(response, url);
    }
}
